import os
import requests
import wget
import hashlib
import tarfile


def has_new_ver(ver_fname, ver_url):
    "有新版本返回True，没有返回False"
    # 如果本地没有版本文件则有新版本
    if not os.path.isfile(ver_fname):
        return True

    # 比较本地版本文件和远程版本
    r = requests.get(ver_url)
    with open(ver_fname) as fobj:
        local_ver = fobj.read()
    if local_ver != r.text:
        return True
    else:
        return False


def file_ok(fname, md5_url):
    "如果本地与远程md5值一致返回True，否则返回False"
    m = hashlib.md5()
    with open(fname, 'rb') as fobj:
        while 1:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)

    r = requests.get(md5_url)
    if m.hexdigest() != r.text.strip():  # 去除r.text尾部的\n
        return False
    else:
        return True


def deploy(app_fname, deploy_dir, dest):
    "用于部署程序"
    # 解压缩
    tar = tarfile.open(app_fname)
    tar.extractall(deploy_dir)
    tar.close()

    # 拼接出解压目录的绝对路径
    app_dir = os.path.basename(app_fname)
    app_dir = app_dir.replace('.tar.gz', '')
    app_dir = os.path.join(deploy_dir, app_dir)

    #　判断dest是否存在，存在先将其删除
    if os.path.exists(dest):
        os.remove(dest)

    os.symlink(app_dir, dest)


if __name__ == '__main__':
    # 判断是否有新版本，没有则退出
    ver_fname = '/var/www/deploy/live_ver'
    ver_url = 'http://192.168.1.110/deploy/live_ver'
    if not has_new_ver(ver_fname, ver_url):
        print('没有发现新版本。')
        exit(1)

    # 下载新版本程序
    r = requests.get(ver_url)
    pkg_url = 'http://192.168.1.110/deploy/pkgs/myweb-%s.tar.gz' % r.text
    app_fname = '/var/www/download/myweb-%s.tar.gz' % r.text
    wget.download(pkg_url, app_fname)

    # 检查程序是否损坏，如果损坏则删除它
    md5_url = pkg_url + '.md5'
    if not file_ok(app_fname, md5_url):
        print('文件已损坏。')
        os.remove(app_fname)
        exit(2)

    # 部署程序
    deploy_dir = '/var/www/deploy'
    dest = '/var/www/html/zh'
    deploy(app_fname, deploy_dir, dest)

    # 更新本地软件版本
    if os.path.exists(ver_fname):
        os.remove(ver_fname)
    wget.download(ver_url, ver_fname)
